package top.winshu.starter;

import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.winshu.common.util.IdGenerator;
import top.winshu.common.util.SpringContextUtil;
import top.winshu.common.web.config.GlobalExceptionAdvice;
import top.winshu.common.web.config.WebLogAspect;
import top.winshu.common.web.config.WebMvcConfigure;

import java.math.BigInteger;

/**
 * @author winshu
 * @since 2021/1/28
 **/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WinshuProperties.class)
public class WinshuAutoConfiguration implements InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(WinshuAutoConfiguration.class);

    private final WinshuProperties winshuProperties;

    public WinshuAutoConfiguration(WinshuProperties winshuProperties) {
        this.winshuProperties = winshuProperties;
        LOGGER.info(">>>>> 初始化 WinshuAutoConfiguration");
    }

    @Override
    public void afterPropertiesSet() {
        IdGenerator.init(winshuProperties.getMachineId());
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        // FIX: 前端js解析Long只支持到16位，如超过16位会造成精度丢失。序列化时将Long转成String
        return jacksonObjectMapperBuilder -> {
            jacksonObjectMapperBuilder.serializerByType(BigInteger.class, ToStringSerializer.instance);
            jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
        };
    }

    @Bean
    @ConditionalOnMissingBean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    @ConditionalOnMissingBean
    public GlobalExceptionAdvice globalExceptionAdvice() {
        return new GlobalExceptionAdvice();
    }

    @Bean
    public WebMvcConfigurer webMvcConfigure() {
        return new WebMvcConfigure();
    }

    @Bean
    @ConditionalOnMissingBean
    public WebLogAspect webLogAspect() {
        return new WebLogAspect();
    }

    @Bean
    @ConditionalOnMissingBean
    public SpringContextUtil springContextUtil() {
        return new SpringContextUtil();
    }
}
